package gs.sr.tkfxz.server;

import gs.sr.tkfxz.client.TaokeItemSearch;
import gs.sr.tkfxz.shared.FieldVerifier;
import gs.sr.tkfxz.shared.ReqParam;
import gs.sr.tkfxz.shared.TaokeItem;
import gs.sr.tkfxz.shared.TopAppInfo;
import gs.sr.tkfxz.shared.TopParameters;
import gs.sr.tkfxz.shared.TopReqParam;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.domain.Item;
import com.taobao.api.domain.TaobaokeItem;
import com.taobao.api.internal.util.TaobaoUtils;
import com.taobao.api.request.ItemGetRequest;
import com.taobao.api.request.TaobaokeItemsConvertRequest;
import com.taobao.api.response.ItemGetResponse;
import com.taobao.api.response.TaobaokeItemsConvertResponse;

@SuppressWarnings("serial")
public class TaokeItemSearchImpl extends RemoteServiceServlet implements
		TaokeItemSearch {

	/**
	 * client
	 */
	private static final TaobaoClient client = new DefaultTaobaoClient(
			TopAppInfo.serverUrl, TopAppInfo.appKey, TopAppInfo.appSecret);

	private static final String default_fields_item_get = "detail_url,num_iid,title,nick,type,cid,seller_cids,props,input_pids,input_str,desc,pic_url,num,valid_thru,list_time,delist_time,stuff_status,location,price,post_fee,express_fee,ems_fee,has_discount,freight_payer,has_invoice,has_warranty,has_showcase,modified,increment,approve_status,postage_id,product_id,auction_point,property_alias,item_img,prop_img,sku,video,outer_id,is_virtual";
	private static final String default_fields_taoke_get = "click_url,shop_click_url,seller_credit_score,num_iid,title,nick";
	private static final String default_fields_taoke_convert = "click_url,num_iid,commission,commission_rate,commission_num,commission_volume";

	private boolean collectTopReqParam(ReqParam rp) {
		boolean b = false;
		/**
		 * top param
		 */
		// @SuppressWarnings("unchecked")
		// Map<String, String[]> pm = super.getThreadLocalRequest()
		// .getParameterMap();
		Map<String, String> pm = rp.getOtherParam();
		if (pm != null) {
			try {
				TopReqParam topReqParam = TopReqParam.parseReqParam(pm);
				if (topReqParam != null
						&& topReqParam.getTop_appkey()
								.equals(TopAppInfo.appKey)) {
					boolean v = TaobaoUtils.verifyTopResponse(
							topReqParam.getTop_parameters(),
							topReqParam.getTop_session(),
							topReqParam.getTop_sign(),
							topReqParam.getTop_appkey(), TopAppInfo.appSecret);
					if (v) {
						rp.setSessionKey(topReqParam.getTop_session());
						Map<String, String> m = TaobaoUtils
								.decodeTopParams(topReqParam
										.getTop_parameters());
						TopParameters topParameters = TopParameters
								.parseTopParameters(m);
						if (StringUtils.isNotBlank(topParameters
								.getVisitor_nick())) {
							rp.setUserNick(topParameters.getVisitor_nick());
							b = true;
						}
					}
				}
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return b;
	}

	@Override
	public TaokeItem search(ReqParam reqParam) throws IllegalArgumentException {
		if (!collectTopReqParam(reqParam)) {
			throw new IllegalArgumentException("invalid top request!");
		}
		Long itemId = reqParam.getItemId();
		if (itemId == null) {
			itemId = FieldVerifier.getItemId(reqParam.getItemUrl());
		}
		if (itemId != null) {
			reqParam.setItemId(itemId); // reset
			TaokeItem r = getTaokeItemBaseInfo(reqParam);
			if (r != null) {
				fillItemInfo(reqParam, r);
				// return to frontend
				r.setRebateAccount(reqParam.getUserNick());
			}
			return r;
		}
		return null;
	}

	private TaokeItem getTaokeItemBaseInfo(ReqParam reqParam) {
		TaokeItem taokeItem = null;
		try {
			TaobaokeItemsConvertResponse resp = convert(reqParam.getUserNick(),
					reqParam.getItemId());
			if (resp.isSuccess()) {
				List<TaobaokeItem> l = resp.getTaobaokeItems();
				if (l != null && l.size() == 1) {
					taokeItem = convert(l.get(0));
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return taokeItem;
	}

	private TaokeItem convert(TaobaokeItem taobaokeItem) {
		TaokeItem taokeItem = new TaokeItem();
		try {
			BeanUtils.copyProperties(taokeItem, taobaokeItem);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return taokeItem;
	}

	private void fillItemInfo(ReqParam reqParam, TaokeItem dest) {
		ItemGetResponse resp;
		try {
			resp = get(reqParam.getItemId(), reqParam.getSessionKey());
			if (resp.isSuccess()) {
				Item item = resp.getItem();
				if (item != null) {
					fillItemInfo(dest, item);
				}
			}
		} catch (ApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void fillItemInfo(TaokeItem dest, Item orig) {
		if (orig.getNumIid().longValue() != dest.getNumIid().longValue()) {
			throw new IllegalArgumentException(
					"invalid arg of itemId! taokeItem.id=["
							+ dest.getNumIid().longValue() + "] and item.id=["
							+ orig.getNumIid().longValue() + "]");
		}
		dest.setPicUrl(orig.getPicUrl());
		dest.setTitle(orig.getTitle());
		dest.setPrice(orig.getPrice());
		// TODO
	}

	private static TaobaokeItemsConvertResponse convert(String nick, long itemId)
			throws ApiException {
		TaobaokeItemsConvertRequest req = new TaobaokeItemsConvertRequest();
		req.setFields(default_fields_taoke_convert);
		req.setNick(nick);
		req.setNumIids(Long.toString(itemId));
		TaobaokeItemsConvertResponse response = client.execute(req);
		return response;
	}

	// private static TaobaokeItemsDetailGetResponse get(String nick, long
	// itemId)
	// throws ApiException {
	// TaobaokeItemsDetailGetRequest req = new TaobaokeItemsDetailGetRequest();
	// req.setFields(default_fields_taoke_get);
	// req.setNick(nick);
	// req.setNumIids(Long.toString(itemId));
	//
	// TaobaokeItemsDetailGetResponse response = client.execute(req);
	//
	// return response;
	// }

	private static ItemGetResponse get(long itemId, String sessionKey)
			throws ApiException {
		ItemGetRequest req = new ItemGetRequest();
		req.setFields(default_fields_item_get);
		req.setNumIid(itemId);
		ItemGetResponse response = client.execute(req, sessionKey);
		return response;
	}

}
